package com.itheima.service.impl;


import com.alibaba.dubbo.config.annotation.Service;
import com.itheima.constant.MessageConstant;
import com.itheima.dao.MenuDao;
import com.itheima.pojo.Menu;
import com.itheima.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * 菜单业务层
 */
@Service(interfaceClass = MenuService.class)
@Transactional
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuDao menuDao;

    /**
     * 通过用户名动态获取菜单数据
     */
    @Override
    public List<Menu> getMenuByName(String username) {
        // 通过用户获取一级菜单获取
        List<Menu> MenuOnes = menuDao.getMenuFistLevelOneByName(username);
        // 递归判断获取子集
        List<Menu> resMenus = this.getChildrens(MenuOnes,username);
        return resMenus;
    }

    /**
     * 根据条件动态查询查询菜单列表
     */
    @Override
    public List<Menu> getMenuList(String queryString) {
        // 根据条件查询菜单列表
        List<Menu> MenuOnes = menuDao.getMenuList(queryString);
        // 递归判断获取子集
        List<Menu> resMenus = this.getChildrens(MenuOnes);
        return resMenus;
    }

    /**
     * 根据menuId删除菜单项
     */
    @Override
    public void deleteById(Integer menuId) {

        //通过menuId查询和role的关联
        int count = menuDao.findRolesByMenuId(menuId);
        if (count > 0) {
            // 有关联连 不删除
            throw new RuntimeException(MessageConstant.DELETE_MENU_FAIL3);
        }
        // 通过menuId查询是否和自己有关联
        List<Menu> menuList = menuDao.findMenuByMid(menuId);
        if (menuList != null && menuList.size() > 0) {
            // 有关联连 不删除
            throw new RuntimeException(MessageConstant.DELETE_MENU_FAIL2);
        }

        // 是最后一级就删除菜单
        menuDao.deleteById(menuId);
    }


    /**
     * 回显一级菜单数据
     */
    @Override
    public List<Menu> getLevel1Menu() {
        return menuDao.getLevel1Menu();
    }


    /**
     * 递归查询子集
     */
    private List<Menu> getChildrens(List<Menu> menus,String username) {
        // 非空判断
        if (menus != null && menus.size() > 0) {
            for (Menu menu : menus) {
                // 通过菜单的id子查询子集
                List<Menu> menuList = menuDao.findMenuByMidAndName(menu.getId(),username);
                //判空有就添加到children属性中
                if (menuList != null && menuList.size() > 0) {
                    menu.setChildren(menuList);
                    this.getChildrens(menuList,username);
                }
            }
        }
        return menus;
    }

    /**
     * 递归查询子集
     */
    private List<Menu> getChildrens(List<Menu> menus) {
        // 非空判断
        if (menus != null && menus.size() > 0) {
            for (Menu menu : menus) {
                // 通过菜单的id子查询子集
                List<Menu> menuList = menuDao.findMenuByMid(menu.getId());
                //判空有就添加到children属性中
                if (menuList != null && menuList.size() > 0) {
                    menu.setChildren(menuList);
                    this.getChildrens(menuList);
                }
            }
        }
        return menus;
    }

    /**
     * 新增菜单
     */
    @Override
    public void add(Menu menu) {
        //判断新增菜单是否为一级菜单
        if (menu != null) {
            //新增一级菜单
            if (menu.getId() == 0) {
                //获取最新priority和path
                Map map = menuDao.getMaxPriAndPath();
                //插入数据库
                String path = (String) map.get("path");
                Integer priority = (Integer) map.get("priority") + 1;
                menu.setPath((Integer.valueOf(path)+1)+"");
                menu.setPriority(priority);
                menu.setLevel(1);
                menuDao.add(menu);
            }else{
                //设置为二级菜单
                menu.setLevel(2);
                //设置父菜单的id
                menu.setParentMenuId(menu.getId());
                //新增二级菜单
                //根据用户选择的一级菜单查询对应的二级菜单
                List<Menu>menuList=menuDao.getMenuListByLevelId(menu.getId());
                if(menuList==null||menuList.size()==0){
                   //拿到一级菜单对象
                    Menu menu1 =menuDao.getMenuById(menu.getId());
                    //代表该一级菜单没有对应的二级菜单
                    String path ="/"+menu1.getPath()+"-1";
                    menu.setPath(path);
                    menu.setPriority(1);
                    //插入二级菜单(一级菜单的第一个二级菜单)
                    menuDao.add(menu);
                }else{
                    //根据已有的二级菜单进行添加(拿到最后一个二级菜单对象)
                    Menu menuLast = menuList.get(menuList.size()-1);
                    //拿到上一个二级菜单的属性 path、priority
                    String[] split = menuLast.getPath().split("-");
                    String prefix =  split[0];
                    String suffix =  (Integer.valueOf(split[1])+1)+"";
                    String path =prefix+"-"+suffix;
                    Integer priority =menuLast.getPriority()+1;
                    menu.setPath(path);
                    menu.setPriority(priority);
                   //插入数据库(一级菜单的第N个二级菜单)
                   menuDao.add(menu);
                }

            }

        }
    }

    /**
     * 根据menuId查询Menu对象
     */
    @Override
    public Menu getMenu(Integer menuId) {
        Menu menu = menuDao.getMenuById(menuId);
        //设置menu对象的id为parentid
        if(menu.getParentMenuId()==null){
            menu.setId(0);
        }
        menu.setId(menu.getParentMenuId());
        return menu;
    }

    /**
     * 编辑菜单
     */
    @Override
    public void edit(Menu menu) {
          //id=null 未选择 关系不变  id=0 升级为一级菜单  本来是一级 就正常
        // 如果 id有值 如果本来是一级 不允许
        // 否则变更为该项子菜单
      if(menu!=null){
          if(menu.getId()==null){
              //用户没有选择所属菜单 直接修改
              menuDao.edit(menu);
          }else if(menu.getId()==0){
              //判断原来是否一级菜单 是修改 否代表要修改为一级
              if(menu.getLevel()==1){
                  menuDao.edit(menu);
              }else{
                  //将二级菜单修改为一级菜单
                  //拿到最新path priority
                  Map map = menuDao.getMaxPriAndPath();
                  String path = (String) map.get("path");
                  Integer priority = (Integer) map.get("priority") + 1;
                  menu.setPath((Integer.valueOf(path)+1)+"");
                  menu.setPriority(priority);
                  menu.setLevel(1);
                  menu.setParentMenuId(null);//一级菜单
                  menuDao.edit(menu);
              }
          }else{
              //来到这代表id有值 也就是所属菜单项存在
              if(menu.getLevel()==1){
                  //如果是一级菜单 不允许修改
                  throw new RuntimeException("一级菜单不能降级！！");
              }else if(menu.getId().equals(menu.getParentMenuId())){//Integer包装类比较
                  //如果原本就是该一级菜单下
                  menuDao.edit(menu);
              }
              // 二级菜单划分到其他一级菜单
               menu.setParentMenuId(menu.getId());
               List<Menu>menuList=menuDao.getMenuListByLevelId(menu.getId());
               if(menuList==null||menuList.size()==0){
                  //拿到一级菜单对象
                  Menu menu1 =menuDao.getMenuById(menu.getId());
                  //代表该一级菜单没有对应的二级菜单
                  String path ="/"+menu1.getPath()+"-1";
                  menu.setPath(path);
                  menu.setPriority(1);
                  menuDao.edit(menu);
              }else{
                  //根据已有的二级菜单进行添加(拿到最后一个二级菜单对象)
                  Menu menuLast = menuList.get(menuList.size()-1);
                  //拿到上一个二级菜单的属性 path、priority
                  String[] split = menuLast.getPath().split("-");
                  String prefix =  split[0];
                  String suffix =  (Integer.valueOf(split[1])+1)+"";
                  String path =prefix+"-"+suffix;
                  Integer priority =menuLast.getPriority()+1;
                  menu.setPath(path);
                  menu.setPriority(priority);
                  menuDao.edit(menu);
              }

          }
      }
    }
    /**
     * 校验菜单名是否重复
     */
    @Override
    public Menu findMenuByName(String name) {
        return menuDao.findMenuByName(name);
    }
}
